# -*- coding: UTF-8 -*-

"""
link_camera.py
主要包含Socket_server类，用于搭建socket服务器，供客户端连接
2020-2-9
"""

import socket  # 导入 socket 模块
from threading import Thread
import os
import gol


class SocketServer:
    def __init__(self, IpAdd, Port):
        """
        SocketServer类的构造函数
        :param IpAdd: 服务器的IP地址
        :param Port: 服务器的端口
        """
        self.IpAdd = IpAdd                                          # IP地址
        self.Port = Port                                            # 端口
        self.SOCKET = socket.socket()                               # socket变量
        self.IsAccept = True                                        # 是否接受连接
        self.DocName = 'CACHE'                                      # 接受图片的保存地址
        self.BASE_DIR = os.path.dirname(os.path.abspath(__file__))  # 该文件的地址 在其他文件调用的时候 为其他文件的位置
        if not os.path.exists(self.DocName):
            # 缓存文件不存在就新建
            os.makedirs(self.DocName)

        self.SOCKET.bind((self.IpAdd, self.Port))
        self.SOCKET.listen(5)
        print('---SOCKET服务器已启动---\nIP:{}\nPORT:{}'.format(self.IpAdd, self.Port))

    def AcceptClient(self):
        """
        服务器开始接收摄像头客户端的连接
        :return: 无
        """
        while self.IsAccept:
            client, addr = self.SOCKET.accept()
            client.sendall(bytes('hello', 'utf8'))      # 发送一串字符串用于判断是否成功连接
            if client.recv(1024).decode() == 'OK':      # 若对方受到，则返回OK字符串，判断成功
                thread = Thread(target=self.HandleMassage, args=(client, addr))     # 建立多线程socket
                thread.setDaemon(True)      # 设置为守护线程 主线程结束时其余线程自动结束
                thread.start()              # 开始线程

    def HandleMassage(self, client, addr):
        """
        从客户端接收信息，保存接收的图片
        :param client: SOCKET连接变量
        :param addr: 客户端IP地址
        :return: 无
        """
        print('服务器连接成功!\n客户端IP:{}'.format(addr))
        pic_inf = client.recv(1024).decode('utf-8', 'ignore')
        while pic_inf == '':                                            # 可能为空字符串，所以添加循环，等待真正的信息到来
            pic_inf = client.recv(1024).decode('utf-8', 'ignore')
        BuildName, ClassName, pic_name, pic_size, time, MaxNum = pic_inf.split('|')   # 分割字符串，划分信息
        pic_name = BuildName + '_' + ClassName + '_' + pic_name
        path = os.path.join(self.BASE_DIR, self.DocName, pic_name)
        pic_size = int(pic_size)
        f = open(path, 'ab')
        has_receive = 0
        client.sendall(bytes('start_send', 'utf8'))                     # 发送开始传输的信息
        while has_receive != pic_size:
            data = client.recv(1024)
            f.write(data)
            has_receive += len(data)
        f.close()
        pic_data = {'BuildName': BuildName, 'ClassName': ClassName, 'Path': path, 'Time': time, 'MaxNum': MaxNum}
        gol.put_queue_value('pic_line', pic_data)                    # 将图片的信息添加到共享队列中，等待预测
        print('成功接收到预测图片')



